﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Controls;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.esriSystem;

namespace hzGis.service.impl
{
    public class PrintService
    {
        /// <summary>
        /// 导入模板
        /// </summary>
        public void ImportTemplate(AxPageLayoutControl PageLayoutControl)
        {
            //打开工程对话框
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "打开模板";
            openFileDialog.Filter = "模板工程|*.mxd";
            openFileDialog.Multiselect = false;
            string filePath = "";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                filePath = openFileDialog.FileName;
            }

            IMapDocument mapDocument = new MapDocument();
            //if (!mapDocument.get_IsPresent(filePath) || !mapDocument.get_IsMapDocument(filePath)) return new Response(Constant.Failure, "工程文件无效!");
           // if (mapDocument.get_IsPasswordProtected(filePath)) return new Response(Constant.Failure, "工程文件已加密无法打开!");

            //打开工程文件
            mapDocument.Open(filePath, string.Empty);

            //获取模板要素
            IGraphicsContainer GraphicsContainer = mapDocument.PageLayout as IGraphicsContainer;
            IMapFrame mMapFrame = GraphicsContainer.FindFrame(mapDocument.ActiveView.FocusMap) as IMapFrame;
            mMapFrame.Map.ClearLayers();

            //获取当前布局要素
            IGraphicsContainer pGraphicsContainer = PageLayoutControl.PageLayout as IGraphicsContainer;
            IMapFrame pMapFrame = pGraphicsContainer.FindFrame(PageLayoutControl.ActiveView.FocusMap) as IMapFrame;
            IPageLayout pPageLayout = PageLayoutControl.PageLayout;

            //替换单位
            IPage mPage = mapDocument.PageLayout.Page;
            pPageLayout.Page.Units = mPage.Units;
            pPageLayout.Page.Orientation = mPage.Orientation;

            //替换页面尺寸
            double dWith, dHeight;
            mPage.QuerySize(out dWith, out dHeight);
            pPageLayout.Page.PutCustomSize(dWith, dHeight);

            //替换数据框尺寸
            IEnvelope env = new Envelope() as IEnvelope;
            IElement mIElement = mMapFrame as IElement;
            mIElement.QueryBounds(PageLayoutControl.ActiveView.ScreenDisplay as IDisplay, env);
            IElement pIElement = pMapFrame as IElement;
            pIElement.Geometry = env;
            PageLayoutControl.ActiveView.GraphicsContainer.AddElement(pIElement, 0);

            //读取布局所有要素
            GraphicsContainer.Reset();
            IElement pElement = GraphicsContainer.Next();
            while (pElement != null)
            {
                PageLayoutControl.ActiveView.GraphicsContainer.AddElement(pElement, 0);
                pElement = GraphicsContainer.Next();
            }
            PageLayoutControl.ActiveView.Refresh();
            mapDocument.Close();

        }

        /// <summary>
        /// 添加打印的标题
        /// </summary>
        /// <param name="title">标题内容</param>
        /// <param name="PageLayoutControl">布局对象</param>
        public IElement addTitle(string title, AxPageLayoutControl PageLayoutControl, 
            double xmin, double ymin, double xmax, double ymax, double fontSize, byte[] textColor, string name)
        {
            ITextElement textElement;
            ITextSymbol textSymbol;
            IColor color;
            IActiveView activeView = PageLayoutControl.PageLayout as IActiveView;
            IEnvelope envelope = new Envelope() as IEnvelope;
            envelope.PutCoords(xmin, ymin, xmax, ymax);
            textElement = new TextElement() as ITextElement;
            IElement element = textElement as IElement;
            element.Geometry = envelope;
            textElement.Text = title;
            textSymbol = new TextSymbol();
            IRgbColor pColor = new RgbColor();
            pColor.Red = textColor[0];
            pColor.Green = textColor[1];
            pColor.Blue = textColor[2];
            color = pColor;
            textSymbol.Color = color;
            textSymbol.Size = fontSize;
            textElement.Symbol = textSymbol;
            IGraphicsContainer graphicsContainer = activeView as IGraphicsContainer;
            graphicsContainer.AddElement(element, 0);
            PageLayoutControl.ActiveView.Refresh();
            return element;
        }

        /// <summary>
        /// 添加指北针
        /// </summary>
        /// <param name="pageLayout"></param>
        /// <param name="map"></param>
        /// <param name="minx"></param>
        /// <param name="miny"></param>
        /// <param name="maxx"></param>
        /// <param name="maxy"></param>
        /// <param name="northArrowName"></param>
        public void AddNorthArrow(ESRI.ArcGIS.Carto.IPageLayout pageLayout, ESRI.ArcGIS.Carto.IMap map, double minx, double miny, double maxx, double maxy, string northArrowName)
        {

            if (pageLayout == null || map == null)
            {
                return;
            }
            ESRI.ArcGIS.Geometry.IEnvelope envelope = new ESRI.ArcGIS.Geometry.Envelope() as IEnvelope;
            envelope.PutCoords(minx, miny, maxx, maxy); //  Specify the location and size of the north arrow
            ESRI.ArcGIS.esriSystem.IUID uid = new ESRI.ArcGIS.esriSystem.UID();
            uid.Value = northArrowName; // "esriCarto.MarkerNorthArrow";
            // Create a Surround. Set the geometry of the MapSurroundFrame to give it a location
            // Activate it and add it to the PageLayout's graphics container
            ESRI.ArcGIS.Carto.IGraphicsContainer graphicsContainer = pageLayout as ESRI.ArcGIS.Carto.IGraphicsContainer; // Dynamic Cast
            // 设置默认边框
            ISymbolBorder pSymborder = new SymbolBorder() as ISymbolBorder;
            pSymborder.CornerRounding = 0;
            IBorder pBorder = pSymborder;
            IFrameElement fe = new FrameElement() as IFrameElement;
            fe.Border = pBorder;
            ISymbolBackground pSymbolBackground = new SymbolBackground() as ISymbolBackground;
            ISimpleFillSymbol pSimpleFillSymbol = new SimpleFillSymbol() as ISimpleFillSymbol;
            IColor backgroundColor = new RgbColor()
            {
                Red = 255,
                Blue = 255,
                Green = 255
            };
            backgroundColor.Transparency = 255;
            pSimpleFillSymbol.Color = backgroundColor;
            pSymbolBackground.FillSymbol = pSimpleFillSymbol;
            fe.Background = pSymbolBackground;
            IElement pe = (IElement)fe;
            pe.Geometry = envelope as IGeometry;
            graphicsContainer.AddElement(pe, 0);

            ESRI.ArcGIS.Carto.IActiveView activeView = pageLayout as ESRI.ArcGIS.Carto.IActiveView; // Dynamic Cast
            ESRI.ArcGIS.Carto.IFrameElement frameElement = graphicsContainer.FindFrame(map);
            ESRI.ArcGIS.Carto.IMapFrame mapFrame = frameElement as ESRI.ArcGIS.Carto.IMapFrame; // Dynamic Cast
            ESRI.ArcGIS.Carto.IMapSurroundFrame mapSurroundFrame = mapFrame.CreateSurroundFrame(uid as ESRI.ArcGIS.esriSystem.UID, null); // Dynamic Cast
            ESRI.ArcGIS.Carto.IElement element = mapSurroundFrame as ESRI.ArcGIS.Carto.IElement; // Dynamic Cast
            element.Geometry = envelope;
            element.Activate(activeView.ScreenDisplay);
            graphicsContainer.AddElement(element, 0);
            ESRI.ArcGIS.Carto.IMapSurround mapSurround = mapSurroundFrame.MapSurround;
            // Change out the default north arrow
            ESRI.ArcGIS.Carto.IMarkerNorthArrow markerNorthArrow = mapSurround as ESRI.ArcGIS.Carto.IMarkerNorthArrow; // Dynamic Cast
            ESRI.ArcGIS.Display.IMarkerSymbol markerSymbol = markerNorthArrow.MarkerSymbol;
            markerSymbol.Size = 150;
            ESRI.ArcGIS.Display.ICharacterMarkerSymbol characterMarkerSymbol = markerSymbol as ESRI.ArcGIS.Display.ICharacterMarkerSymbol; // Dynamic Cast
            characterMarkerSymbol.CharacterIndex = 177; // change the symbol for the North Arrow
            markerNorthArrow.MarkerSymbol = characterMarkerSymbol;
            
        }

        /// <summary>
        /// 添加图片
        /// </summary>
        /// <param name="axPageLayoutControl"></param>
        /// <param name="minx"></param>
        /// <param name="miny"></param>
        /// <param name="maxx"></param>
        /// <param name="maxy"></param>
        /// <param name="fileName">图片地址</param>
        public IElement addPicture(AxPageLayoutControl axPageLayoutControl, double minx, double miny, double maxx, double maxy, string fileName)
        {
            //创建PageLayout对象
            IPageLayout pPageLayout = axPageLayoutControl.PageLayout;
            //将PageLayout强转成IActiveView

            IGraphicsContainer pGraphicsContainer = (IGraphicsContainer)pPageLayout;
            IActiveView pActiveView = (IActiveView)pPageLayout;
            IPictureElement pPictureElement = new PngPictureElement() as IPictureElement;
            pPictureElement.ImportPictureFromFile(fileName);
            //图片在缩放的时候长宽保持比例
            pPictureElement.MaintainAspectRatio = true;
            //添加图片的附加描述信息
            //string ms=pPictureElement.PictureDescription ;
            //确定这张图片是否会被保存到mxd上
            //pPictureElement.SavePictureInDocument = true;
            IFrameElement pFrameElement = axPageLayoutControl.GraphicsContainer.FindFrame(axPageLayoutControl.ActiveView.FocusMap);
            IElement pElement;
            pElement = pFrameElement as IElement;
            IEnvelope pEnvelop = pElement.Geometry.Envelope;
            IElement pElementPic = pPictureElement as IElement;
            IEnvelope pEnvelopNew = new Envelope() as IEnvelope;
            pEnvelopNew.XMin = minx;
            pEnvelopNew.YMin = miny;
            pEnvelopNew.XMax = maxx;
            pEnvelopNew.YMax = maxy;
            pElementPic.Geometry = pEnvelopNew;
            pGraphicsContainer.AddElement(pElementPic, -10);
            pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
            return pElementPic;
        }

        public IElement addRectangle(AxPageLayoutControl axPageLayoutControl, double minx, double miny, double maxx, double maxy, byte[] borderColors, double borderWidth, byte[] backgroundColors)
        {
            //创建PageLayout对象
            IPageLayout pPageLayout = axPageLayoutControl.PageLayout;
            //将PageLayout强转成IActiveView
            IGraphicsContainer pGraphicsContainer = (IGraphicsContainer)pPageLayout;
            // 设置外框
            IEnvelope rectangle = new Envelope() as IEnvelope;
            // 设置外框的大小
            rectangle.PutCoords(minx, miny, maxx, maxy);
            // 添加外框
            IFrameElement fe = new FrameElement() as IFrameElement;
            // 设置边框
            ISymbolBorder pSymborder = new SymbolBorder() as ISymbolBorder;
            pSymborder.CornerRounding = 0;
            ILineSymbol lineSymbol = new SimpleLineSymbol();
            lineSymbol.Width = borderWidth;
            IRgbColor borderColor = new RgbColor(){
                Red = borderColors[0],
                Green = borderColors[1],
                Blue = borderColors[2]
            };
            lineSymbol.Color = borderColor;
            pSymborder.LineSymbol = lineSymbol;
            IBorder pBorder = pSymborder;
            fe.Border = pBorder;
            IElement pe = (IElement)fe;
            pe.Geometry = rectangle as IGeometry;
            
            ISymbolBackground pSymbolBackground = new SymbolBackground() as ISymbolBackground;
            ISimpleFillSymbol pSimpleFillSymbol = new SimpleFillSymbol() as ISimpleFillSymbol;
            IColor backgroundColor = new RgbColor()
            {
                Red = backgroundColors[0],
                Green = backgroundColors[1],
                Blue = backgroundColors[2],
            };
            backgroundColor.Transparency = 255;
            pSimpleFillSymbol.Color = backgroundColor;
            pSymbolBackground.FillSymbol = pSimpleFillSymbol;
            fe.Background = pSymbolBackground;
            pGraphicsContainer.AddElement(pe, 10);
            return pe;
        }


        public void addAnnotate(AxPageLayoutControl axPageLayoutControl, double minx, double miny, double maxx, double maxy, string annotate)
        {
            //创建PageLayout对象
            IPageLayout pPageLayout = axPageLayoutControl.PageLayout;
            //将PageLayout强转成IActiveView
            IGraphicsContainer pGraphicsContainer = (IGraphicsContainer)pPageLayout;
            IActiveView pActiveView = (IActiveView)pPageLayout;
        }

        public void PrintAuto(IActiveView pActiveView)
        {

            IPaper pPaper = new Paper();
            IPrinter pPrinter = new EmfPrinter() as IPrinter;
            System.Drawing.Printing.PrintDocument sysPrintDocumentDocument = new System.Drawing.Printing.PrintDocument();
            pPaper.PrinterName = sysPrintDocumentDocument.PrinterSettings.PrinterName;
            int Resolution = pPrinter.Resolution;
            double w, h;
            IEnvelope PEnvelope = pActiveView.Extent;
            w = PEnvelope.Width;
            h = PEnvelope.Height;
            double pw = 65.34, ph = 42.2;//纸张
            pPrinter.QueryPaperSize(out pw, out ph);
            tagRECT userRECT = pActiveView.ExportFrame;
            userRECT.left = (int)(pPrinter.PrintableBounds.XMin * Resolution);
            userRECT.top = (int)(pPrinter.PrintableBounds.YMin * Resolution);
            if ((w / h) > (pw / ph))//以宽度来调整高度
            {
                userRECT.right = userRECT.left + (int)(pPrinter.PrintableBounds.Width * Resolution);
                userRECT.bottom = userRECT.top + (int)((pPrinter.PrintableBounds.Width * Resolution) * h / w);
            }
            else
            {
                userRECT.bottom = userRECT.top + (int)(pPrinter.PrintableBounds.Height * Resolution);
                userRECT.right = userRECT.left + (int)(pPrinter.PrintableBounds.Height * Resolution * w / h);
            }
            IEnvelope pDriverBounds = new Envelope() as IEnvelope;
            pDriverBounds.PutCoords(userRECT.left, userRECT.top, userRECT.right, userRECT.bottom);
            ITrackCancel pCancel = new CancelTracker() as ITrackCancel;
            int hdc = pPrinter.StartPrinting(pDriverBounds, 0);
            pActiveView.Output(hdc, pPrinter.Resolution,ref userRECT, pActiveView.Extent, pCancel);
            pPrinter.FinishPrinting();
        }

        public void PrintPro(AxPageLayoutControl axPageLayoutControl, string path)
        {
            IExport pExport = new ExportPDF() as IExport;
            pExport.ExportFileName = path;
            int resolution = 96;
            pExport.Resolution = resolution;
            IPrintAndExport docPrintExport = new PrintAndExport();
            docPrintExport.Export(axPageLayoutControl.ActiveView, pExport, resolution, false, null);
        }

        /// <summary>
        /// 打印PageLayout
        /// </summary>
        /// <param name="pPageLayout">PageLayout对象</param>
        public void PrintPageLayout(AxPageLayoutControl pPageLayout)
        {
            try
            {
                if (pPageLayout.Printer != null)
                {
                    IPrinter pPrinter = pPageLayout.Printer;
                    if (pPrinter.Paper.Orientation != pPageLayout.Page.Orientation)
                    {
                        pPrinter.Paper.Orientation = pPageLayout.Page.Orientation;
                    }
                    pPageLayout.PrintPageLayout(1, 0, 0);
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        public void deleteElement(AxPageLayoutControl axPageLayoutControl, IElement element)
        {
            IPageLayout pPageLayout = axPageLayoutControl.PageLayout;
            //将PageLayout强转成IActiveView
            IGraphicsContainer pGraphicsContainer = (IGraphicsContainer)pPageLayout;
            pGraphicsContainer.DeleteElement(element);
        }

        /// <summary>
        /// 绘制行号
        /// </summary>
        /// <param name="axPageLayoutControl"></param>
        /// <param name="xmin"></param>
        /// <param name="ymin"></param>
        /// <param name="xmax"></param>
        /// <param name="ymax"></param>
        /// <param name="content"></param>
        /// <param name="textColor"></param>
        /// <param name="fontSize"></param>
        public ITextElement drawLine(AxPageLayoutControl axPageLayoutControl, double xmin, double ymin, 
            double xmax, double ymax, string content, int[] textColor, int fontSize, double angle)
        {
            ITextElement textElement;
            ITextSymbol textSymbol;
            IColor color;
            IActiveView activeView = axPageLayoutControl.PageLayout as IActiveView;
            IEnvelope envelope = new Envelope() as IEnvelope;
            envelope.PutCoords(xmin, ymin, xmax, ymax);
            textElement = new TextElement() as ITextElement;
            IElement element = textElement as IElement;
            element.Geometry = envelope;
            textElement.Text = content;
            textSymbol = new TextSymbol();
            IRgbColor pColor = new RgbColor();
            pColor.Red = textColor[0];
            pColor.Green = textColor[1];
            pColor.Blue = textColor[2];
            textSymbol.Angle = angle;
            color = pColor;
            textSymbol.Color = color;
            textSymbol.Size = fontSize;
            textElement.Symbol = textSymbol;
            IGraphicsContainer graphicsContainer = activeView as IGraphicsContainer;
            graphicsContainer.AddElement(element, 0);
            
            return textElement;
        }
    }
}
